package tk.winshu.shortestpath.model;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

/**
 * 抽象节点
 *
 * @author winshu
 * @since 2019/10/19.
 */
public abstract class NObject {

    private static final double DEFAULT_SIZE = 50D;

    /**
     * index，标识一个唯一对象
     */
    private int index;
    private Rectangle2D shape;

    protected NObject() {
    }

    protected NObject(int index, double x, double y) {
        this.index = index;
        this.setShape(x, y);
    }

    /**
     * 绘制节点
     */
    protected void draw(Graphics2D g2d, Image image, Color color, boolean isDrawShape) {
        AffineTransform t = new AffineTransform();
        t.translate(getRealLocation().getX(), getRealLocation().getY());
        t.scale(1, 1);

        if (image != null) {
            g2d.drawImage(image, t, null);
        }
        if (color != null) {
            g2d.setColor(color);
        }
        if (isDrawShape) {
            g2d.draw(getShape());
        }
        g2d.drawString(getIndex() + "", (float) getRealLocation().getX(), (float) getRealLocation().getY());
    }

    public double getHeight() {
        return this.shape.getHeight();
    }

    /**
     * 获取标识
     */
    public int getIndex() {
        return index;
    }


    public Rectangle2D getShape() {
        return shape;
    }

    public double getWidth() {
        return this.shape.getWidth();
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public void setLocation(double x, double y) {
        setShape(x, y);
    }

    public void setLocation(Point2D point) {
        setLocation(point.getX(), point.getY());
    }

    /**
     * maybe for fast.json
     */
    public void setLocation(Point2D.Double point) {
        setLocation(point.getX(), point.getY());
    }

    /**
     * 获取以中心点的坐标
     */
    public Point2D getLocation() {
        return new Point2D.Double(this.shape.getCenterX(), this.shape.getCenterY());
    }

    /**
     * 获取以左上角为中心的坐标
     */
    public Point2D getRealLocation() {
        return new Point2D.Double(this.shape.getX(), this.shape.getY());
    }

    /**
     * 判断某个坐标是否在当前节点上
     */
    public boolean isContainsPoint(Point2D point) {
        return this.shape.contains(point);
    }

    /**
     * 设置图形及坐标
     */
    private void setShape(double px, double py) {
        if (this.shape == null) {
            this.shape = new Rectangle2D.Double();
        }
        this.shape.setFrame(px - DEFAULT_SIZE / 2, py - DEFAULT_SIZE / 2, DEFAULT_SIZE, DEFAULT_SIZE);
    }

    @Override
    public int hashCode() {
        return Integer.valueOf(getIndex()).hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof NObject)) {
            return false;
        }
        return ((NObject) obj).index == index;
    }

}
